/*
 * Union.java
 *
 * Created on 23 marzo 2004, 22.17
 */

package net.ermannofranco.xml.schema;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.ermannofranco.xml.Static;

/**
 * oggetto Union.
 * 
 * @author ermanno (ermanno.franco@gmail.com)
 */
public class Union extends SchemaTag implements BaseTypeContainer {

	private static final long serialVersionUID = 1671725370584646423L;
	private int counter = 0;
	private final Set<ContentType> types = new HashSet<ContentType>();

	/**
	 * Creates a new instance of Union
	 * 
	 * @param level
	 *            livello di indentazione
	 * @param container
	 *            oggetto contenitore
	 */
	protected Union(int level, ISchemaTag container) {
		super("union", level, container);
	}

	/**
	 * imposta i tipi membro
	 * 
	 * @param memberTypes
	 *            imposta i tipi membro
	 * @return autoref
	 */
	public Union setMemberTypes(SimpleType... memberTypes) {
		if (memberTypes == null || memberTypes.length == 0) {
			throw new SchemaException("member types size not valid in union");
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < memberTypes.length; i++) {
			types.add(memberTypes[i]);
			sb.append(feedFormPrefix(memberTypes[i].getTypeName()));
			sb.append(Static.SPACE);
		}
		sb.setLength(sb.length() - 1);
		addAttr("memberTypes", sb.toString());// controllare QNames
		counter++;
		return this;
	}

	/**
	 * aggiunge un simpletype
	 * 
	 * @return autoref
	 */
	public SimpleType addSimpleType() {
		SimpleType t;
		add(t = new SimpleType(getLevel() + 1, this));
		types.add(t);
		counter++;
		return t;
	}

	/**
	 * aggiunge un simpletype
	 * 
	 * @param name
	 *            nome del tipo
	 * @return ref all'oggetto creato
	 */
	// public SimpleType addSimpleType(SimpleType typeRef) {
	// return addSimpleType().setName(typeRef.getTypeName());
	// }

	/**
	 * semplica override di convalida
	 * 
	 * @return super.toString()
	 */
	public String toPrint() {
		if (counter == 0)
			throw new SchemaException(
					"Assegnare contenuto o memberTypes a union");
		return super.toPrint();
	}

	public String toSave() {
		if (counter == 0)
			throw new SchemaException(
					"Assegnare contenuto o memberTypes a union");
		return super.toSave();
	}

	/**
	 * aggiunge un tag Annotation che contiene un tag Documentation
	 * 
	 * @param explanation
	 *            Stringa di documentazione
	 * @return autoriferimento all'oggetto corrente
	 */
	public Union addDocumentation(String explanation) {
		addAnnotation().addDocumentation(explanation);
		return this;
	}

	/**
	 * aggiunge un tag Annotation che contiene un tag Documentation
	 * 
	 * @param explanation
	 *            testo della documentazione
	 * @param language
	 *            attributo di xml:lang, seguire le regole di i18n
	 * @return riferimento all'oggetto corrente
	 */
	public Union addDocumentation(String explanation, String language) {
		addAnnotation().addDocumentation(explanation, language);
		return this;
	}

	public List<XmlType> getBaseTypes() {
		Set<XmlType> ret = new HashSet<XmlType>();
		for (ContentType type : types) {
			ret.addAll(type.getBaseTypes());
		}
		return new ArrayList<XmlType>(ret);
	}
}
